package com.vogue.flowmeter.api.retrofit;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;


/**
 *RSA 加密工具
 */
public final class RSAUtils
{
    private static String RSA = "RSA/ECB/PKCS1Padding";

    /**
     * 通过公钥byte[](publicKey.getEncoded())将公钥还原，适用于RSA算法
     *
     * @param keyBytes
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     */
    public static PublicKey getPublicKey(byte[] keyBytes) throws NoSuchAlgorithmException,
            InvalidKeySpecException
    {
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(RSA);
        PublicKey publicKey = keyFactory.generatePublic(keySpec);
        return publicKey;
    }

    /**
     * 通过私钥byte[]将公钥还原，适用于RSA算法
     *
     * @param keyBytes
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     */
    public static PrivateKey getPrivateKey(byte[] keyBytes) throws NoSuchAlgorithmException,
            InvalidKeySpecException
    {
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(RSA);
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
        return privateKey;
    }


    /**
     * 得到公钥
     *
     * @param key
     *            密钥字符串（经过base64编码）
     * @throws Exception
     */
    public static PublicKey getPublicKey(String key) throws Exception {
        byte[] keyBytes;
        //keyBytes= Base64Utils.decode(key);
        //keyBytes= Base64Utils.base64Decode(key);
        keyBytes= android.util.Base64.decode(key, android.util.Base64.NO_WRAP);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(keySpec);
        return publicKey;
    }


/**
 * 得到私钥
 *
 * @param key
 *            密钥字符串（经过base64编码）
 * @throws Exception
 */
    public static PrivateKey getPrivateKey(String key) throws Exception {
        byte[] keyBytes;
        //keyBytes= Base64Utils.decode(key);
        //keyBytes= Base64Utils.base64Decode(key);
        keyBytes= android.util.Base64.decode(key, android.util.Base64.NO_WRAP);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
        return privateKey;
    }

    /**
     * 使用公钥对明文进行加密
     * @param publicKey      公钥
     * @param plainText      明文
     * @return
     */
    public static String encrypt(String publicKey, String plainText){
        try {
            Cipher cipher = Cipher.getInstance(RSA);
            cipher.init(Cipher.ENCRYPT_MODE,getPublicKey(publicKey));
            byte[] bytes = plainText.getBytes();
            ByteArrayInputStream read = new ByteArrayInputStream(bytes);
            ByteArrayOutputStream write = new ByteArrayOutputStream();
            byte [] buf=new byte[117];
            int len=0;
            while ( (len=read.read(buf))!=-1 ){
                byte [] buf1=null;
                if(buf.length==len){
                    buf1=buf;
                }else{
                    buf1=new byte[len];
                    for (int i = 0; i < len; i++) {
                        buf1[i]=buf[i];
                    }
                }
                byte[] bytes1 = cipher.doFinal(buf1);
                write.write(bytes1);
            }
            //return Base64Utils.base64Encode(write.toByteArray());
            return android.util.Base64.encodeToString(write.toByteArray(), android.util.Base64.NO_WRAP);
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 使用私钥对密文进行解密
     * @param privateKey       私钥
     * @param enStr            密文
     * @return
     */
    public static String decrypt(String privateKey, String enStr){
        try {
            Cipher cipher = Cipher.getInstance(RSA);
            cipher.init(Cipher.DECRYPT_MODE, getPrivateKey(privateKey));
            //Base64Utils.base64Decode(enStr);
            byte[] bytes = android.util.Base64.decode(enStr, android.util.Base64.NO_WRAP);

            ByteArrayInputStream read = new ByteArrayInputStream(bytes);
            ByteArrayOutputStream write = new ByteArrayOutputStream();
            byte [] buf=new byte[128];
            int len=0;
            while ( (len=read.read(buf))!=-1 ){
                byte [] buf1=null;
                if(buf.length==len){
                    buf1=buf;
                }else{
                    buf1=new byte[len];
                    for (int i = 0; i < len; i++) {
                        buf1[i]=buf[i];
                    }
                }
                byte[] bytes1 = cipher.doFinal(buf1);
                write.write(bytes1);
            }
            return new String(write.toByteArray());
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}
